package emulator.hardware.clock;

import java.util.LinkedList;
import java.util.List;
import java.util.Observer;

public class ClockImpl2 implements Clock {

	private static int sync_threshhold = 10;

	private List<ClockHandleImpl2> handles = new LinkedList<ClockHandleImpl2>();
	private int active_handles = 0;
	private long system_ticks = 0;
	private TickScales tick_scales = new TickScales();

	public ClockImpl2()
	{
		tick_scales.init();
	}
	
	@Override
	synchronized public ClockHandle acquireHandle() {
		ClockHandleImpl2 handle = new ClockHandleImpl2(this);
		handles.add(handle);
		active_handles++;
		return handle;
	}

	@Override
	public void releaseHandle(ClockHandle handle) {
		handles.remove(handle);
	}

	synchronized public void requestTicks(ClockHandleImpl2 handle) {
		active_handles--;
		assert(active_handles >= 0);
		while (active_handles == 0)
		{
			for (ClockHandleImpl2 handle_i : handles)
			{
				if (handle_i.grantTicks(sync_threshhold))
					active_handles++;
			}
			system_ticks += sync_threshhold;
		}
		if ((system_ticks % 1000) == 0)
			tick_scales.measureTicks(system_ticks);
	}

	public long getFrequency() {
		return tick_scales.getClockSpeed();
	}

	synchronized public long getTicks() {
		return system_ticks;
	}

	public void addClockSpeedObserver(Observer observer) {
		tick_scales.addObserver(observer);
	}
}
